package com.atguigu.tingshu.search.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import co.elastic.clients.elasticsearch._types.aggregations.LongTermsAggregate;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.NestedQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.CompletionSuggestOption;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.Suggestion;
import co.elastic.clients.json.JsonData;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.StringUtils;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.model.album.*;
import com.atguigu.tingshu.model.base.BaseEntity;
import com.atguigu.tingshu.model.search.AlbumInfoIndex;
import com.atguigu.tingshu.model.search.AttributeValueIndex;
import com.atguigu.tingshu.model.search.SuggestIndex;
import com.atguigu.tingshu.query.search.AlbumIndexQuery;
import com.atguigu.tingshu.search.repository.AlbumInfoIndexRepository;
import com.atguigu.tingshu.search.repository.SuggestIndexRepository;
import com.atguigu.tingshu.search.service.SearchService;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.search.AlbumInfoIndexVo;
import com.atguigu.tingshu.vo.search.AlbumSearchResponseVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.suggest.Completion;
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;


@Slf4j
@Service
@SuppressWarnings({"all"})
public class SearchServiceImpl implements SearchService {

    private static final String SUGGEST_INDEX = "suggestinfo";
    //专辑索引库名称
    private static final String INDEX_NAME = "albuminfo";
    @Autowired
    private AlbumInfoIndexRepository albumInfoIndexRepository;
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private AlbumFeignClient albumFeignClient;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private ElasticsearchClient elasticsearchClient;
    @Autowired
    private SuggestIndexRepository suggestIndexRepository;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 构建专辑索引库文件对象，新增专辑到索引库
     *
     * @param albumId
     */
    @Override
    public void upperAlbum(Long albumId) {
        //创建索引库的对象
        AlbumInfoIndex albumInfoIndex = new AlbumInfoIndex();

        //创建一个有异步返回值的对象
        CompletableFuture<AlbumInfo> albumInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(albumId).getData();
            // 断言抛出异常
            Assert.notNull(albumInfo, "专辑为信息空");
            // 复制信息
            BeanUtil.copyProperties(albumInfo, albumInfoIndex);

            //2.远程调用专辑服务获取专辑属性列表 封装专辑属性列表
            List<AlbumAttributeValue> albumAttributeValueVoList = albumInfo.getAlbumAttributeValueVoList();
            Assert.notNull(albumAttributeValueVoList, "专辑标签为空");
            if (CollectionUtil.isNotEmpty(albumAttributeValueVoList)) {
                //将集合类型AlbumAttributeValue转为AttributeValueIndex类型
                List<AttributeValueIndex> attributeValueIndexList =
                        albumAttributeValueVoList.stream().map(albumAttributeValue -> {
                            return BeanUtil.copyProperties(albumAttributeValue, AttributeValueIndex.class);
                        }).collect(Collectors.toList());
                albumInfoIndex.setAttributeValueIndexList(attributeValueIndexList);
            }
            return albumInfo;
        }, threadPoolExecutor);


        //3.远程调用用户服务获取用户信息,为索引库文档对象中相关属性值
        albumInfoCompletableFuture.thenAcceptAsync(albumInfo -> {
            UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(albumInfo.getUserId()).getData();
            Assert.notNull(userInfoVo, "主播信息不存在");
            albumInfoIndex.setAnnouncerName(userInfoVo.getNickname());
            // 远程调用信息库的分类信息 索引文库中的信息复制
            BaseCategoryView categoryView = albumFeignClient.getCategoryView(albumInfo.getCategory3Id()).getData();
            Assert.notNull(categoryView, "分类信息不存在！");
            //设置属性值
            albumInfoIndex.setCategory1Id(categoryView.getCategory1Id());
            albumInfoIndex.setCategory2Id(categoryView.getCategory2Id());
        }, threadPoolExecutor);

        //4.手动随机生成统计值，为索引库文档对象中相关属性赋值

        int num1 = new Random().nextInt(1000);
        int num2 = new Random().nextInt(800);
        int num3 = new Random().nextInt(500);
        int num4 = new Random().nextInt(200);
        albumInfoIndex.setPlayStatNum(num1);
        albumInfoIndex.setSubscribeStatNum(num2);
        albumInfoIndex.setBuyStatNum(num3);
        albumInfoIndex.setCommentStatNum(num4);
        //  设置热度排名
        albumInfoIndex.setHotScore(num1 * 0.1 + num2 * 0.2 + num3 * 0.4 + num4 * 0.3);

        //6.保存专辑文档对象到索引库
        albumInfoIndexRepository.save(albumInfoIndex);

        //将上架专辑中 专辑标题 专辑作者名称 存入提词索引库
        this.saveSuggestDoc(albumInfoIndex);
    }

    private void saveSuggestDoc(AlbumInfoIndex albumInfoIndex) {
        //1.处理专辑标题
        String albumTitle = albumInfoIndex.getAlbumTitle();
        SuggestIndex suggestIndexAlbumTile = new SuggestIndex();
        suggestIndexAlbumTile.setId(IdUtil.fastSimpleUUID());
        suggestIndexAlbumTile.setTitle(albumTitle);
        suggestIndexAlbumTile.setKeyword(new Completion(new String[]{albumTitle}));
        suggestIndexAlbumTile.setKeywordPinyin(new Completion(new String[]{PinyinUtil.getPinyin(albumTitle, "")}));
        suggestIndexAlbumTile.setKeywordSequence(new Completion(new String[]{PinyinUtil.getFirstLetter(albumTitle,
                "")}));

        //2.处理作者名称
        String announcerName = albumInfoIndex.getAnnouncerName();
        SuggestIndex suggestIndexAnnouncerName = new SuggestIndex();
        suggestIndexAnnouncerName.setId(IdUtil.fastSimpleUUID());
        suggestIndexAnnouncerName.setTitle(announcerName);
        suggestIndexAnnouncerName.setKeyword(new Completion(new String[]{announcerName}));
        suggestIndexAnnouncerName.setKeywordPinyin(new Completion(new String[]{PinyinUtil.getPinyin(announcerName,
                "")}));
        suggestIndexAnnouncerName.setKeywordSequence(new Completion(new String[]{PinyinUtil.getFirstLetter(announcerName, "")}));

        suggestIndexRepository.saveAll(Arrays.asList(suggestIndexAlbumTile, suggestIndexAnnouncerName));
    }

    /**
     * 专辑下架
     *
     * @param albumId
     */
    @Override
    public void lowerAlbum(Long albumId) {
        albumInfoIndexRepository.deleteById(albumId);
    }

    /**
     * 根据多条件进行检索过滤专辑数据
     *
     * @param queryVo
     * @return
     */
    @Override
    public AlbumSearchResponseVo search(AlbumIndexQuery queryVo) {
        try {
            //1.封装检索请求对象
            SearchRequest searchRequest = this.buildDSL(queryVo);
            //2.执行检索
            SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(searchRequest,
                    AlbumInfoIndex.class);
            //3.解析ES响应数据
            return this.parseResult(searchResponse, queryVo);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 基于检索条件对象封装检索请求对象
     *
     * @param queryVo
     * @return
     */

    @Override
    public SearchRequest buildDSL(AlbumIndexQuery queryVo) {
        //1.创建请求构建器对象
        SearchRequest.Builder searchRequestBuiler = new SearchRequest.Builder().index(INDEX_NAME);
        //1.1 设置query 查询过滤条件
        BoolQuery.Builder allBoolQueryBuilder = new BoolQuery.Builder();
        //1.1.1 设置关键字查询
        String keyword = queryVo.getKeyword();
        if (StringUtils.isNotBlank(keyword)) {
            BoolQuery.Builder keyWordBoolBuilder = new BoolQuery.Builder();
            keyWordBoolBuilder.should(s -> s.match(m -> m.field("albumTitle").query(keyword)));
            keyWordBoolBuilder.should(s -> s.match(m -> m.field("albumIntro").query(keyword)));
            keyWordBoolBuilder.should(s -> s.match(m -> m.field("announcerName").query(keyword)));
            allBoolQueryBuilder.must(keyWordBoolBuilder.build()._toQuery());
        }
        //1.1.2 设置分类过滤条件
        Long category1Id = queryVo.getCategory1Id();
        if (category1Id != null) {
            allBoolQueryBuilder.filter(f -> f.term(t -> t.field("category1Id").value(category1Id)));
        }
        Long category2Id = queryVo.getCategory2Id();
        if (category2Id != null) {
            allBoolQueryBuilder.filter(f -> f.term(t -> t.field("category2Id").value(category2Id)));
        }
        Long category3Id = queryVo.getCategory3Id();
        if (category3Id != null) {
            allBoolQueryBuilder.filter(f -> f.term(t -> t.field("category3Id").value(category3Id)));
        }
        //1.1.2 设置专辑属性过滤条件
        List<String> attributeList = queryVo.getAttributeList();
        if (!CollectionUtils.isEmpty(attributeList)) {
            //以：进行分割，分割后应该是2个元素，属性id:属性值id (以-分割的字符串)
            for (String attribute : attributeList) {
                String[] split = attribute.split(":");
                if (split != null && split.length == 2) {
                    Query nestedQuery = NestedQuery.of(n ->
                            n.path("attributeValueIndexList")
                                    .query(q ->
                                            q.bool(b ->
                                                    b.must(m -> m.term(t -> t.field("attributeValueIndexList" +
                                                                    ".attributeId").value(split[0])))
                                                            .must(m -> m.term(t -> t.field("attributeValueIndexList" +
                                                                    ".valueId").value(split[1])))
                                            )))._toQuery();
                    allBoolQueryBuilder.filter(nestedQuery);
                }
            }
        }
        searchRequestBuiler.query(allBoolQueryBuilder.build()._toQuery());

        //1.2 设置分页
        Integer pageNo = queryVo.getPageNo();
        Integer pageSize = queryVo.getPageSize();
        Integer from = (pageNo - 1) * pageSize;
        searchRequestBuiler.from(from).size(pageSize);


        //1.3 设置排序
        String order = queryVo.getOrder();
        String orderField = "";
        String sort = "";
        if (StringUtils.isNotBlank(order)) {
            String[] split = order.split(":");
            if (split != null && split.length == 2) {
                switch (split[0]) {
                    case "1":
                        orderField = "hotScore";
                        break;
                    case "2":
                        orderField = "playStatNum";
                        break;
                    case "3":
                        orderField = "createTime";
                        break;
                }
                sort = split[1];
            }
            String finalOrderField = orderField;
            String finalSort = sort;
            searchRequestBuiler.sort(s -> s.field(f -> f.field(finalOrderField).order("asc".equals(finalSort) ?
                    SortOrder.Asc : SortOrder.Desc)));
        }

        //1.4 设置高亮
        if (StringUtils.isNotBlank(keyword)) {
            searchRequestBuiler.highlight(h -> h.fields("albumTitle", f -> f.preTags("<font color='red'>").postTags(
                    "</font>")));
        }

        //1.5 设置查询返回索引库字段
        searchRequestBuiler.source(s -> s.filter(f -> f.excludes("attributeValueIndexList", "hotScore")));

        return searchRequestBuiler.build();
    }

    /**
     * 解析ES检索结果，封装自定义结果
     *
     * @param response ·
     * @param queryVo
     * @return
     */
    @Override
    public AlbumSearchResponseVo parseResult(SearchResponse<AlbumInfoIndex> response, AlbumIndexQuery queryVo) {
        AlbumSearchResponseVo vo = new AlbumSearchResponseVo();
        //1.封装分页信息
        long total = response.hits().total().value();
        Integer pageSize = queryVo.getPageSize();
        long totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
        vo.setTotal(total);
        vo.setPageSize(pageSize);
        vo.setTotalPages(totalPage);
        vo.setPageNo(queryVo.getPageNo());

        //2.封装业务数据
        List<Hit<AlbumInfoIndex>> hits = response.hits().hits();
        if (CollectionUtil.isNotEmpty(hits)) {
            List<AlbumInfoIndexVo> albumInfoIndexVoList = hits.stream().map(hit -> {
                //获取专辑对象
                AlbumInfoIndex albumInfoIndex = hit.source();
                //处理高亮
                Map<String, List<String>> highlightMap = hit.highlight();
                if (CollectionUtil.isNotEmpty(highlightMap)) {
                    if (highlightMap.containsKey("albumTitle")) {
                        //获取高亮关键字
                        String albumTitle = highlightMap.get("albumTitle").get(0);
                        albumInfoIndex.setAlbumTitle(albumTitle);
                    }
                }
                return BeanUtil.copyProperties(albumInfoIndex, AlbumInfoIndexVo.class);
            }).collect(Collectors.toList());

            vo.setList(albumInfoIndexVoList);
        }
        return vo;
    }

    @Override
    public List<Map<String, Object>> getCategory3Top6Hot(Long category1Id) {
        try {
            //1.远程调用专辑服务-得到入参中一级分类下包含前7个三级分类列表
            List<BaseCategory3> category3List = albumFeignClient.getTop7BaseCategory3(category1Id).getData();
            Assert.notNull(category3List, "三级分类为空");

            //1.1 获取集合中七个分类 获取7个三级分类ID
            List<Long> category3IdList = category3List.stream().map(BaseCategory3::getId).collect(Collectors.toList());

            //1.2 将三级分类集合转为Map map中key：三级分类ID  map中value:三级分类对象
            //category3List.stream().collect(Collectors.toMap(
            //        baseCategory3 -> {
            //            //返回Map中Key
            //            return baseCategory3.getId();
            //        },
            //        //返回Map中Value
            //        baseCategory3 -> {
            //            return baseCategory3;
            //        }
            //));
            Map<Long, BaseCategory3> category3Map =
                    category3List.stream().collect(Collectors.toMap(BaseCategory3::getId,
                            baseCategory3 -> baseCategory3));

            //1.3 将三级分类ID转为多关键字精确查询List条件对象FieldValue
            List<FieldValue> fieldValueList =
                    category3IdList.stream().map(c3Id -> FieldValue.of(c3Id)).collect(Collectors.toList());

            //2.构建检索DSL语句
            //2.1 创建检索请求构建器对象，指定检索索引库名称
            SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder();
            searchRequestBuilder.index(INDEX_NAME);
            //2.2 设置查询条件-根据七个三级分类ID-多关键字精确查询
            searchRequestBuilder.query(q -> q.terms(tq -> tq.field("category3Id").terms(t -> t.value(fieldValueList))));
            //2.3 设置业务数据返回为0
            searchRequestBuilder.size(0);
            //2.4 设置三级分类聚合，子聚合（获取热度前6专辑）
            searchRequestBuilder.aggregations("category3Agg",
                    a -> a.terms(t -> t.field("category3Id"))
                            .aggregations("top6", a1 -> a1.topHits(t -> t.size(6).sort(s -> s.field(f -> f.field(
                                    "hotScore").order(SortOrder.Desc)))))
            );

            //3.执行检索
            SearchRequest searchRequest = searchRequestBuilder.build();
            System.out.println("本次检索聚合DSL：");
            System.out.println(searchRequest.toString());
            SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(searchRequest,
                    AlbumInfoIndex.class);

            //4.解析ES聚合结果
            //4.1 获取ES响应聚合结果中三级分类聚合对象
            Aggregate category3Agg = searchResponse.aggregations().get("category3Agg");
            LongTermsAggregate category3IdLterms = category3Agg.lterms();

            //4.2 遍历三级分类集合桶（Bucket） 每遍历一次产生“当前分类热门专辑Map” 将Map收集List
            List<Map<String, Object>> listResult = category3IdLterms.buckets().array().stream().map(category3Bucket -> {
                Map<String, Object> map = new HashMap<>();
                //4.2.1 遍历当前三级分类ID内部，获取三级分类ID
                long category3Id = category3Bucket.key();
                //4.2.2 获取热门前6子聚合对象 得到 热门专辑列表
                List<Hit<JsonData>> top6 = category3Bucket.aggregations().get("top6").topHits().hits().hits();
                if (CollectionUtil.isNotEmpty(top6)) {
                    List<AlbumInfoIndex> hotAlbumList = top6.stream().map(hit -> {
                        //将聚合到业务数据Hit类型转为 AlbumInfoIndex类型
                        String sourceJsonStr = hit.source().toString();
                        return JSON.parseObject(sourceJsonStr, AlbumInfoIndex.class);
                    }).collect(Collectors.toList());
                    map.put("list", hotAlbumList);
                }
                map.put("baseCategory3", category3Map.get(category3Id));
                return map;
            }).collect(Collectors.toList());
            return listResult;
        } catch (Exception e) {
            log.error("[专辑服务]热门专辑异常：{}", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<String> completeSuggest(String keyword) {
        try {

            //1.构建检索请求对象，封装检索索引库名称
            SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder();
            searchRequestBuilder.index(SUGGEST_INDEX);
            //1.1 设置建议词请求体参数
            searchRequestBuilder.suggest(
                    s -> s.suggesters("suggestKeyword",
                                    f -> f.prefix(keyword).completion(c -> c.field("keyword").size(10).skipDuplicates(true)))
                            .suggesters("suggestKeywordPinyin", f -> f.prefix(keyword).completion(c -> c.field(
                                    "keywordPinyin").size(10).skipDuplicates(true).fuzzy(fu -> fu.fuzziness("auto"))))
                            .suggesters("suggestKeywordSquenece", f -> f.prefix(keyword).completion(c -> c.field(
                                    "keywordSequence").size(10).skipDuplicates(true).fuzzy(fu -> fu.fuzziness("auto"))))
            );

            //2.执行检索
            SearchRequest searchRequest = searchRequestBuilder.build();
            System.out.println("提词DSL：");
            System.err.println(searchRequest.toString());
            SearchResponse<SuggestIndex> searchResponse = elasticsearchClient.search(searchRequest, SuggestIndex.class);

            //3.解析ES响应建议结果
            //3.1 准备单例集合（能去重重复建议词）
            Set<String> titleSet = new HashSet<>();
            titleSet.addAll(this.parseSugggestResult(searchResponse, "suggestKeyword"));
            titleSet.addAll(this.parseSugggestResult(searchResponse, "suggestKeywordPinyin"));
            titleSet.addAll(this.parseSugggestResult(searchResponse, "suggestKeywordSquenece"));
            //3.2 判断命中提示词数量小于10
            if (titleSet.size() < 10) {
                //通过普通检索 检索提词索引库 利用匹配查询返回结果
                SearchResponse<SuggestIndex> response =
                        elasticsearchClient.search(s -> s.index(SUGGEST_INDEX).query(q -> q.match(m -> m.field("title"
                        ).query(keyword))), SuggestIndex.class);
                List<Hit<SuggestIndex>> hits = response.hits().hits();
                if (CollectionUtil.isNotEmpty(hits)) {
                    for (Hit<SuggestIndex> hit : hits) {
                        SuggestIndex suggestIndex = hit.source();
                        titleSet.add(suggestIndex.getTitle());
                        //如果添加后大于等于10
                        if (titleSet.size() > 10) {
                            break;
                        }
                    }
                }
            }
            return new ArrayList<>(titleSet).subList(0, 10);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 不同分类下的不同的排行榜
     */
    @Override
    public void updateLatelyAlbumRanking() {
        try {
            //1.远程调用专辑服务获取一级分类列表
            List<BaseCategory1> baseCategory1List = albumFeignClient.getAllCategory1().getData();
            Assert.notNull(baseCategory1List, "1级分类列表为空");

            List<Long> category1IdList =
                    baseCategory1List.stream().map(BaseCategory1::getId).collect(Collectors.toList());

            //2.循环一级分类列表，根据一级分类ID，以及当前分类下：固定5中排序方式查询ES中专辑列表；将不同排行数据存入Redis
            for (Long baseCategory1Id : category1IdList) {
                //2.0 声明当前分类热度数据hash结构的key
                String rankingKey = RedisConstant.RANKING_KEY_PREFIX + baseCategory1Id;
                //2.1 构建排序字段数组（热度、播放量、订阅量、购买量、评论量）
                String[] rankingDimensionArray = new String[]{"hotScore", "playStatNum", "subscribeStatNum",
                        "buyStatNum", "commentStatNum"};

                //2.2 循环排序字段数组-发起ES检索请求
                for (String dimension : rankingDimensionArray) {
                    SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(
                            s -> s.index(INDEX_NAME)
                                    .query(q -> q.term(t -> t.field("category1Id").value(baseCategory1Id)))
                                    .sort(sort -> sort.field(f -> f.field(dimension).order(SortOrder.Desc)))
                                    .source(source -> source.filter(f -> f.excludes("attributeValueIndexList",
                                            "hotScore",
                                            "category1Id",
                                            "category2Id",
                                            "category3Id")))
                            , AlbumInfoIndex.class);
                    //2.3 解析ES命中不同排行数据
                    List<Hit<AlbumInfoIndex>> hits = searchResponse.hits().hits();
                    if (CollectionUtil.isNotEmpty(hits)) {
                        List<AlbumInfoIndex> albumInfoIndexList =
                                hits.stream().map(hit -> hit.source()).collect(Collectors.toList());
                        //2.4 将数据存入Redis-Hash结构中
                        redisTemplate.opsForHash().put(rankingKey, dimension, albumInfoIndexList);
                    }
                }
            }
        } catch (Exception e) {
            log.error("[专辑]热门检索异常：{}", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * 获取Redis中不同分类下不同排序方式-专辑排行榜
     *
     * @param category1Id
     * @param dimension
     * @return
     */
    @Override
    public List<AlbumInfoIndex> getRankingList(Long category1Id, String dimension) {
        //1.构建分类热门专辑Key
        String rankingKey = RedisConstant.RANKING_KEY_PREFIX + category1Id;
        //2.获取Hash结构中Val
        List<AlbumInfoIndex> list = (List<AlbumInfoIndex>) redisTemplate.opsForHash().get(rankingKey, dimension);
        return list;
    }

    private Collection<String> parseSugggestResult(SearchResponse<SuggestIndex> searchResponse, String suggestKeyword) {
        List<String> list = new ArrayList<>();
        //1.获取提词结果Map
        Map<String, List<Suggestion<SuggestIndex>>> suggestMap = searchResponse.suggest();
        List<Suggestion<SuggestIndex>> suggestionList = suggestMap.get(suggestKeyword);
        //2.获取提词结果命中选项options
        for (Suggestion<SuggestIndex> suggestIndexSuggestion : suggestionList) {
            for (CompletionSuggestOption<SuggestIndex> option : suggestIndexSuggestion.completion().options()) {
                //获取提词选项中_source
                SuggestIndex suggestIndex = option.source();
                list.add(suggestIndex.getTitle());
            }
        }
        return list;

    }
}




